﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	public static partial class Logs
	{
		/// <summary>
		/// 资源代码。
		/// </summary>
		internal const string ResourceCode = "LogManage";

		/// <summary>
		/// 资源标识。
		/// </summary>
		internal readonly static Guid ResourceId = new Guid("fa1a3691-9a7e-43a8-ac45-9e02c431fd7d");

		/// <summary>
		/// 资源名称。
		/// </summary>
		internal const string ResourceName = "日志管理";

		/// <summary>
		/// 资源描述。
		/// </summary>
		internal const string ResourceDescription = "";

		/// <summary>
		/// 权限码
		/// </summary>
		public enum PermissionCode
		{
			Delete = 15,
			Clear = 31
		}

		/// <summary>
		/// 注册权限。
		/// </summary>
		internal static void RegisterPermissions()
		{
			ResourceCategories.RegisterSystemManage();
			RegisterCategoryResource();
			RegisterResourcePermissions();
		}

		/// <summary>
		/// 注册资源类别下的资源。
		/// </summary>
		/// <returns>注册的资源。</returns>
		private static Resource RegisterCategoryResource()
		{
			Resource resource = new Resource();
			resource.CategoryId = ResourceCategories.SystemManageResourceCategoryId;
			resource.ResourceId = ResourceId;
			resource.ResourceCode = ResourceCode;
			resource.ResourceName = ResourceName;
			resource.Description = ResourceDescription;

			return Resources.Register(resource);
		}

		/// <summary>
		/// 注册资源下的权限。
		/// </summary>
		private static void RegisterResourcePermissions()
		{
			Permission permission;

			permission = new Permission();
			permission.ResourceId = ResourceId;
			permission.PermissionCode = (int)PermissionCode.Delete;
			permission.PermissionName = "删除";
			permission.Description = "";
			Permissions.Register(permission);

			permission = new Permission();
			permission.ResourceId = ResourceId;
			permission.PermissionCode = (int)PermissionCode.Clear;
			permission.PermissionName = "清除";
			permission.Description = "";
			Permissions.Register(permission);
		}
	}



	/// <summary>
	/// Logs 类。
	/// </summary>
	public static partial class Logs
	{
		public const string INFO_TYPE = "Log";

		#region GetItem
		/// <summary>
		/// 根据标识获取指定的日志。
		/// </summary>
		/// <param name="o">日志集合。</param>
		/// <param name="logId">获取的日志标识 LogId。</param>
		/// <returns>获取的信息项。</returns>
		public static Log GetItem(this System.Data.Linq.Table<Log> o, int logId)
		{
			return o.SingleOrDefault(p => p.LogId == logId);
		}

		/// <summary>
		/// 根据标识获取指定的日志。
		/// </summary>
		/// <param name="logId">获取的日志标识 LogId。</param>
		/// <returns>获取的信息项。</returns>
		public static Log GetItem(int logId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Logs.GetItem(logId);
		}
		#endregion



		#region Exists
		/// <summary>
		/// 验证指定的日志是否已经存在。
		/// </summary>
		/// <param name="o">日志集合。</param>
		/// <param name="logId">验证的日志标识 LogId。</param>
		/// <returns>布尔值表示指定的日志是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<Log> o, int logId)
		{
			return o.Any(p => p.LogId == logId);
		}

		/// <summary>
		/// 验证指定的日志是否已经存在。
		/// </summary>
		/// <param name="logId">验证的日志标识 LogId。</param>
		/// <returns>布尔值表示指定的日志是否已经存在。</returns>
		public static bool Exists(int logId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Logs.Exists(logId);
		}
		#endregion
	}



	/// <summary>
	/// Logs 类操作部分。
	/// </summary>
	public static partial class Logs
	{
		#region Insert
		/// <summary>
		/// 添加日志。
		/// </summary>
		/// <param name="insertedLog">添加的日志。</param>
		/// <returns>添加的日志。</returns>
		internal static Log Insert(GenericModuleDataContext dc, Log insertedLog)
		{
			Log log = insertedLog.ToNewEntity<Log>();
			log.UserId = Users.CurrentUserId;
			log.LogTime = DateTime.Now;
			log.SiteId = Sites.CurrentSiteId;

			try
			{
				System.Web.HttpContext context = System.Web.HttpContext.Current;
				if (context != null)
				{
					log.OperationUrl = context.Request.Url.AbsoluteUri;
					log.Ip = context.Request.UserHostAddress;
				}
			}
			catch (Exception err)
			{
				log.OperationUrl = "无法获取操作的URL地址。";
			}

			dc.Logs.InsertOnSubmit(log);
			dc.SubmitChanges();

			// 返回只读数据
			return insertedLog.FillByEntity(log);
		}

		/// <summary>
		/// 添加日志。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="resourceId">操作资源标识。</param>
		/// <param name="permissionCode">操作的权限代码。</param>
		/// <param name="infoType">操作的信息所属类别。</param>
		/// <param name="infoId">操作的信息标识。</param>
		/// <param name="operation">进行的操作。</param>
		/// <param name="content">操作的内容。</param>
		/// <returns>添加的日志。</returns>
		internal static Log Insert(GenericModuleDataContext dc, Guid? resourceId, int? permissionCode, string infoType, string infoId, string operation, string content)
		{
			Log log = new Log()
			{
				ResourceId = resourceId,
				PermissionCode = permissionCode,
				InfoType = infoType,
				InfoId = infoId,
				Operation = operation,
				Content = content
			};
			return Insert(dc, log);
		}
		#endregion



		#region Delete
		/// <summary>
		/// 删除日志。
		/// </summary>
		/// <param name="logId">删除的日志标识 LogId。</param>
		public static void Delete(int logId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Log log = dc.Logs.GetItem(logId);
			if (log == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetDeleteRight(dc, log, true);	// 权限验证

			Delete(dc, log);

			// 记录日志
			Insert(dc, ResourceId, (int)PermissionCode.Delete, INFO_TYPE, log.LogId.ToString(), PermissionCode.Delete.ToString(), log.Content);

			dc.SubmitChanges();
		}

		#region internal Delete
		internal static void Delete(GenericModuleDataContext dc, Log log)
		{
			dc.Logs.DeleteOnSubmit(log);
		}
		#endregion
		#endregion



		#region Clear
		/// <summary>
		/// 清除日志。
		/// </summary>
		/// <param name="logId">清除的日志标识 LogId。</param>
		public static void Clear()
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			GetClearRight(dc, true);	// 权限验证

			dc.ExecuteCommand("Truncate Table Logs");

			// 记录日志
			Insert(dc, ResourceId, (int)PermissionCode.Clear, INFO_TYPE, null, PermissionCode.Clear.ToString(), null);
		}
		#endregion
	}



	/// <summary>
	/// Logs 类对应操作权限部分。（受限站点资源。）
	/// </summary>
	public static partial class Logs
	{
		#region GetDeleteRight
		/// <summary>
		/// 获取当前用户是否有删除日志的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="log">删除的日志对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除日志的权限。</returns>
		public static bool GetDeleteRight(GenericModuleDataContext dc, Log log, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Delete;
			bool b = dc.AccessController.GetUserIsHasPermission<Log>(userName, log, ResourceId, permissionCode, log.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, log, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有删除日志的权限。
		/// </summary>
		/// <param name="log">删除的日志对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除日志的权限。</returns>
		public static bool GetDeleteRight(Log log, bool triggerException)
		{
			return GetDeleteRight(new GenericModuleDataContext(), log, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除日志的权限。
		/// </summary>
		/// <param name="log">删除的日志对象。</param>
		/// <returns>布尔值表示当前用户是否有删除日志的权限。</returns>
		public static bool GetDeleteRight(Log log)
		{
			return GetDeleteRight(log, false);
		}
		#endregion



		#region GetClearRight
		/// <summary>
		/// 获取当前用户是否有清除日志的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有清除日志的权限。</returns>
		public static bool GetClearRight(GenericModuleDataContext dc, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Clear;
			bool b = dc.AccessController.GetUserIsHasPermission<Log>(userName, null, ResourceId, permissionCode);

			if (triggerException && !b)
				throw new PermissionException(userName, null, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有清除日志的权限。
		/// </summary>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有清除日志的权限。</returns>
		public static bool GetClearRight(bool triggerException)
		{
			return GetClearRight(new GenericModuleDataContext(), triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有清除日志的权限。
		/// </summary>
		/// <returns>布尔值表示当前用户是否有清除日志的权限。</returns>
		public static bool GetClearRight()
		{
			return GetClearRight(false);
		}
		#endregion
	}



	/// <summary>
	/// Logs 类后台管理部分。
	/// </summary>
	public static partial class Logs
	{
		public static bool GetManageListRight()
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, Logs.ResourceId, (int)Logs.PermissionCode.Delete, Sites.CurrentSiteId);
		}

		public static bool GetManageListRight(int? siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, Logs.ResourceId, (int)Logs.PermissionCode.Delete, siteId);
		}




		public struct LogForManageList
		{
			public int LogId { get; set; }
			public string Content { get; set; }
		}

		public static PaginationInfo<List<LogForManageList>> GetPaginationManageList(int? siteId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.Logs
					select new LogForManageList { LogId = p.LogId, Content = p.Content };

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.Content.Contains(keyword));

			PaginationInfo<List<LogForManageList>> pageInfo = new PaginationInfo<List<LogForManageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}



	}
}